package com.inspur.edp.bef.bizentity.util;

import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.cef.designtime.api.collection.GspAssociationCollection;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspEnumValue;
import com.inspur.edp.cef.designtime.api.variable.CommonVariable;
import com.inspur.edp.udt.designtime.api.entity.ComplexDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.SimpleDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnInfo;
import com.inspur.edp.udt.designtime.api.entity.dbInfo.ColumnMapType;
import com.inspur.edp.udt.designtime.api.entity.element.UdtElement;
import com.inspur.edp.udt.designtime.api.entity.enumtype.UseType;
import lombok.var;

import java.util.UUID;

/** 
 更新udt字段
 
*/
public class UpdateBeVariableUtil
{
	/** 
	 创建字段实例
	 
	 @return 
	*/
	private CommonVariable getChildElement()
	{
		CommonVariable tempVar = new CommonVariable();
		tempVar.setID(UUID.randomUUID().toString());
		return tempVar;
	}

	/** 
	 根据引用的udt元数据更新字段(模板约束均更新)
	 
	 @param element
	 @param udt
	*/
//C# TO JAVA CONVERTER TODO TASK: C# optional parameters are not converted to Java:
//ORIGINAL LINE: public void updateElementWithRefUdt(CommonVariable element, UnifiedDataTypeDef udt, bool isFirstChoose = false)
	public final void updateElementWithRefUdt(CommonVariable element, UnifiedDataTypeDef udt, boolean isFirstChoose)
	{
		element.setUdtID(udt.getId());
		element.setUdtName(udt.getName());
		// 其他属性
		if (udt instanceof ComplexDataTypeDef)
		{
			updateComplexDataTypeDefProperties(element, (ComplexDataTypeDef)udt);
		}
		else if (udt instanceof SimpleDataTypeDef)
		{
			updateComplexDataTypeDefProperties(element, (SimpleDataTypeDef)udt, isFirstChoose);
		}
	}

	/** 
	 转换columnInfo为childElement
	 
	 @param info
	 @param prefix
	 @param ele 映射字段
	 @return 
	*/
	public final void mapColumnInfoToField(ColumnInfo info, String prefix, CommonVariable ele)
	{
		if (prefix== null||"".equals(prefix))
		{
			throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0069);
		}

		String newLabelId = prefix + "_" + info.getCode();
		ele.setLabelID(newLabelId);
		ele.setCode( newLabelId);
		ele.setName(info.getName());
		ele.setMDataType(info.getMDataType());
		ele.setDefaultValue(info.getDefaultValue());
		ele.setLength(info.getLength());
		ele.setPrecision(info.getPrecision()); 
	}


		//#region 单值

	/** 
	 根据单值udt更新字段的其他属性
	 
	 @param element
	 @param sUdt
	 @param isFirstChoose 是否首次选择
	*/
	private void updateComplexDataTypeDefProperties(CommonVariable element, SimpleDataTypeDef sUdt, boolean isFirstChoose)
	{
		if (element.getCode()==null || "".equals(element.getCode()))
		{
			element.setCode( sUdt.getCode());
		}
		if (element.getName()==null ||"".equals(element.getName()))
		{
			element.setName(sUdt.getName());
		}

		if (isFirstChoose || isConstraint(sUdt, "DataType"))
		{
			element.setMDataType(sUdt.getMDataType());
		}
		if (isFirstChoose || isConstraint(sUdt, "Length"))
		{
			element.setLength(sUdt.getLength());
		}
		if (isFirstChoose || isConstraint(sUdt, "Precision"))
		{
			element.setPrecision(sUdt.getPrecision());
		}
		if (isFirstChoose || isConstraint(sUdt, "ObjectType"))
		{
			element.setObjectType(sUdt.getObjectType());
			// 关联
			if (element.getChildAssociations() == null)
			{
				element.setChildAssociations(new GspAssociationCollection());
			}

			var belongElement = (element.getChildAssociations() != null && element.getChildAssociations().size() > 0) ? element.getChildAssociations().get(0).getBelongElement() : null;

			var assos = element.getChildAssociations().clone(belongElement);

			element.getChildAssociations().clear();
			if (sUdt.getChildAssociations() != null && sUdt.getChildAssociations().size() > 0)
			{
				throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0081);
				//foreach (GspAssociation item in sUdt.ChildAssociations)
				//{
				//	var beAsso = assos?.Find(asso { return asso.Id == item.Id);
				//	element.ChildAssociations.Add(convertUdtAssociation(item, element, beAsso, isFirstChoose));
				//}
			}

			element.setEnumIndexType(sUdt.getEnumIndexType());
			// 枚举
			element.getContainEnumValues().clear();
			if (sUdt.getContainEnumValues() != null && sUdt.getContainEnumValues().size() > 0)
			{
				for (GspEnumValue item : sUdt.getContainEnumValues())
				{
					element.getContainEnumValues().add(item);
				}
			}
		}
		if (isFirstChoose || isConstraint(sUdt, "DefaultValue"))
		{
			element.setDefaultValue((sUdt.getDefaultValue()==null)? null:sUdt.getDefaultValue().toString());
		}
		if (isFirstChoose || isConstraint(sUdt, "IsRequired"))
		{
			element.setIsRequire(sUdt.getIsRequired());
		}
		// UnifiedDataType属性，前端根据[约束]/[模板]控制属性是否可编辑
		//element.UnifiedDataType = sUdt;
	}

	/** 
	 是否约束
	 
	 @return 
	*/
	private boolean isConstraint(SimpleDataTypeDef sUdt, String propertyName)
	{
		if (sUdt.getPropertyUseTypeInfos().containsKey(propertyName))
		{

			var type = sUdt.getPropertyUseTypeInfos().get(propertyName);
			return type.getPropertyUseType()==UseType.AsConstraint;
		}
		else
		{
			throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0080, propertyName);
		}
	}


		//#endregion


		//#region 多值
	/** 
	 根据多值udt更新字段的其他属性
	 
	 @param element
	 @param cUdt
	*/
	private void updateComplexDataTypeDefProperties(CommonVariable element, ComplexDataTypeDef cUdt)
	{
		if (StringUtil.checkNull(element.getCode()))
		{
			element.setCode( cUdt.getCode());
		}
		if (StringUtil.checkNull(element.getName()))
		{
			element.setName(cUdt.getName());
		}

		UdtElement newElement;
		if (cUdt.getElements().size() == 1 && cUdt.getDbInfo().getMappingType() != ColumnMapType.SingleColumn)
		{
			newElement = (UdtElement)((cUdt.getElements().get(0) instanceof UdtElement) ? cUdt.getElements().get(0) : null);
		}
		else
		{
			newElement = new UdtElement(cUdt.getPropertys());
		}

		element.setObjectType(newElement.getObjectType());

		// 若为[单一列]的映射关系，可能导致超长，需把数据类型改为[Text]
		if (cUdt.getDbInfo().getMappingType() == ColumnMapType.SingleColumn)
		{
			element.setMDataType(GspElementDataType.Text);
			element.setLength(0);
			element.setPrecision(0);
		}
		else
		{
			element.setMDataType(newElement.getMDataType());
			element.setLength(newElement.getLength());
			element.setPrecision(newElement.getPrecision());
		}
		element.setDefaultValue(newElement.getDefaultValue());
		element.getChildAssociations().clear();
		element.getContainEnumValues().clear();
	}

		//#endregion


		//#region 关联
	//vo变量选udt时，不需要更新MappingRelation及ChildElements
	//private GspAssociation convertUdtAssociation(GspAssociation udtAsso, IGspCommonElement ele, GspAssociation beAsso,bool isFirstChoose)
	//{
	//	var asso = new GspAssociation();
	//	asso.Id = udtAsso.Id;
	//	asso.RefModel = ele.BelongObject?.BelongModel;
	//	asso.RefModelCode = udtAsso.RefModelCode;
	//	asso.RefModelID = udtAsso.RefModelID;
	//	asso.RefModelName = udtAsso.RefModelName;
	//	asso.RefModelPkgName = udtAsso.RefModelPkgName;
	//	asso.RefObjectCode = udtAsso.RefObjectCode;
	//	asso.RefObjectID = udtAsso.RefObjectID;
	//	asso.RefObjectName = udtAsso.RefObjectName;
	//	if (udtAsso.KeyCollection.Count > 0)
	//	{
	//		foreach (GspAssociationKey key in udtAsso.KeyCollection)
	//		{
	//			asso.KeyCollection.Add(convertUdtAssoKey(key, ele));
	//		}
	//	}

	//	if (isFirstChoose)
	//	{
	//		if (udtAsso.RefElementCollection.Count > 0)
	//		{
	//			foreach (CommonVariable refEle in udtAsso.RefElementCollection)
	//			{
	//				asso.RefElementCollection.Add(convertUdtRefElement(refEle as UdtElement, ele.LabelID));
	//			}
	//		}
	//	}
	//	else
	//	{
	//		var udtRefElements = udtAsso.RefElementCollection.Clone(null, udtAsso);
	//		// udt带出
	//		if (beAsso != null && beAsso.RefElementCollection != null && beAsso.RefElementCollection.Count != 0)
	//		{
	//			foreach (CommonVariable refEle in beAsso.RefElementCollection)
	//			{
	//				if (refEle.IsFromAssoUdt)
	//				{
	//					var refElement = udtRefElements.Find(item { return item.RefElementId == refEle.RefElementId);
	//					udtRefElements.Remove(refElement);
	//					// udt仍包含，则加上；udt上已删，则不加。
	//					if (refElement != null)
	//					{
	//						var refEle2 = convertUdtRefElement(refElement as UdtElement, ele.LabelID);
	//						refEle2.getID() = refEle.getID();
	//						asso.RefElementCollection.Add(refEle2);
	//					}
	//				}
	//				else
	//				{
	//					asso.RefElementCollection.Add(refEle);
	//				}
	//			}
	//		}
	//		if (udtRefElements.Count > 0)
	//		{
	//			foreach (CommonVariable refEle in udtRefElements)
	//			{
	//				asso.RefElementCollection.Add(convertUdtRefElement(refEle as UdtElement, ele.LabelID));
	//			}
	//		}
	//	}

	//	return asso;
	//}

	//private GspAssociationKey convertUdtAssoKey(GspAssociationKey udtKey, IGspCommonElement ele)
	//{
	//	var key = new GspAssociationKey();
	//	key.SourceElement = udtKey.SourceElement;
	//	key.SourceElementDisplay = udtKey.SourceElementDisplay;
	//	key.TargetElement = ele.getID();
	//	key.TargetElementDisplay = ele.Name;
	//	return key;
	//}

	//private IGspCommonElement convertUdtRefElement(UdtElement udtEle, string prefix)
	//{
	//	var bizEle = new CommonVariable();
	//	//bizEle.getID() = udtEle.getID();
	//	var newLabelId = prefix + "_" + udtEle.LabelID;
	//	bizEle.LabelID = newLabelId;
	//	bizEle.setCode( udtEle.getCode();
	//	bizEle.Name = udtEle.Name;
	//	bizEle.MDataType = udtEle.MDataType;
	//	bizEle.Length = udtEle.Length;
	//	bizEle.Precision = udtEle.Precision;
	//	bizEle.RefElementId = udtEle.RefElementId;
	//	bizEle.IsRefElement = true;
	//	bizEle.IsFromAssoUdt = true;

	//	// udt相关
	//	bizEle.IsUdt = udtEle.IsUdt;
	//	bizEle.UdtID = udtEle.UdtID;
	//	bizEle.UdtName = udtEle.UdtName;
	//	bizEle.UdtPkgName = udtEle.UdtPkgName;
	//	return bizEle;
	//}

		//#endregion
}